package com.weaponlin.stream;

import com.weaponlin.entity.Person;
import com.weaponlin.stream.collector.MyGrouping;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.partitioningBy;

public class CommonCollector {
    // data
    public static List<Person> list = Arrays.asList(
            new Person().setName("lin").setAge(20).setHeight(178.00),
            new Person().setName("lin8").setAge(20).setHeight(178.00),
            new Person().setName("lin7").setAge(21).setHeight(175.00),
            new Person().setName("lin6").setAge(22).setHeight(176.00),
            new Person().setName("lin5").setAge(23).setHeight(178.00),
            new Person().setName("lin4").setAge(21).setHeight(177.00),
            new Person().setName("lin3").setAge(23).setHeight(177.00),
            new Person().setName("lin2").setAge(22).setHeight(176.00),
            new Person().setName("lin1").setAge(20).setHeight(176.00)
    );

    public static void main(String[] args) {
        // joining
        String res1 = Stream.of("1", "2", "3", "4").collect(joining());
        System.out.println(res1);
        String res2 = Stream.of("1", "2", "3", "4").collect(joining(","));
        System.out.println(res2);
        String res3 = Stream.of("1", "2", "3", "4").collect(joining(",", "{", "}"));
        System.out.println(res3);

        // groupingBy
        Map<Integer, List<Person>> groupByAge = list.stream().collect(groupingBy(Person::getAge));
        System.out.println(groupByAge);
        Map<Integer, Map<String, List<Person>>> groupByAgeAndName = list.stream()
                .collect(groupingBy(Person::getAge, groupingBy(Person::getName)));
        System.out.println(groupByAgeAndName);
        Map<Integer, Map<String, Map<Double, List<Person>>>> groupByAgeAndNameAndHeight = list.stream().collect(groupingBy(Person::getAge, groupingBy(Person::getName, groupingBy(Person::getHeight))));
        System.out.println(groupByAgeAndNameAndHeight);

        // partition
        Map<Boolean, List<Person>> isGT20 = list.stream().collect(partitioningBy(e -> e.getAge() > 20));
        System.out.println(isGT20);
        Map<Boolean, Map<Integer, List<Person>>> isGT20AndGroupByAge = list.stream().collect(partitioningBy(e -> e.getAge() > 20, groupingBy(Person::getAge)));
        System.out.println(isGT20AndGroupByAge);

        // custom group by
        Map<Integer, ArrayList<Person>> customGroupByAge = list.stream().collect(new MyGrouping());
        System.out.println(customGroupByAge);
        Map<Integer, ArrayList<Person>> customParallelGroupByAge = list.parallelStream().collect(new MyGrouping());
        System.out.println(customParallelGroupByAge);
    }
}
